<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 * Class Support write and read file log
 *
 * @author Mr.Storm
 */
class My_Logs {
    /**
     * CONST TYPE LOG
     * SERVER_LOG | CONTROLLER_LOG | MONITER_LOG
     */

    const SERVER_LOG = 'sn_s';
    const CONTROLLER_LOG = 'sn_c';
    const MONITER_LOG = 'sn_m';

    /**
     * EXTENSION VARIABLES
     * @var $extend_var | array
     */
    protected $extend_var = array();

    /**
     *  DIRECTORY LOG
     * @var $dir_log | string
     */
    protected $dir_log = '';

    /**
     * FILENAME LOG
     * @var $filename_log | string
     */
    protected $filename_log = '';

    /**
     * Client Id
     * @var $client_id | string
     */
    protected $client_id = null;

    /**
     * initialize object class 
     * singleton
     * @var instance Log
     */
    protected static $instances = NULL;

    /**
     * initialize object class
     * @param type $instance
     * @return instance object class
     */
    public static function instance($instance = My_Logs::SERVER_LOG, array $extend_var = array()) {
        if (!in_array($instance, array('sn_s', 'sn_c', 'sn_m'))) {
            trigger_error(
                    'Instance: ' . $instance .
                    ' in undefined', E_USER_NOTICE);
        }
        if (!isset(self::$instances[$instance])) {
            self::$instances[$instance] = new My_Logs($instance, $extend_var);
        }
        return self::$instances[$instance];
    }

    /**
     * initialize class
     * @param type $instance
     * @param array $extend_var
     * @return \My_Logs
     */
    private function __construct($instance, array $extend_var = array()) {
        // initialize directory and filename log
        $this->dir_log($instance)
                ->filename_log($instance);

        //Set extend variable
        if (!empty($extend_var))
            $this->set($extend_var);

        return $this;
    }

    /**
     * Set or Get dir log
     * @param type $dir directory log
     * @param type $type null | if null return dir
     * @return \My_Logs
     */
    private function dir_log($dir = null, $type = NULL) {
        if ($dir == $type) {
            return $this->dir_log;
        } else {
            $env = getenv('PathApacheLogs');
            $path_logs = $env !== false ? $env : UPLOADPATH . 'logs';
            $this->dir_log = $path_logs . DIRECTORY_SEPARATOR . $dir;
        }
        return $this;
    }

    /**
     * Set or Get filename log
     * @param type $name filename log
     * @param type $type null | if null return dir
     * @return \My_Logs
     */
    private function filename_log($name = null, $type = NULL) {
        if ($name == $type) {
            return $this->filename_log;
        } else {
            $this->filename_log = $name . '_' . date('Ymd') . '.log';
        }
        return $this;
    }

    /**
     * Set and Get client id
     * @param type $client_id
     * @param type $type
     * @return \My_Logs
     */
    public function client_id($client_id = null, $type = NULL) {
        if ($client_id == $type) {
            return $this->client_id;
        } else {
            $this->client_id = $client_id;
        }
        return $this;
    }

    /**
     * Write log
     * @param type $log
     * @return boolean
     */
    public function log($log = '') {
        $message = '';

        $dir_log = $this->dir_log() . DIRECTORY_SEPARATOR;
        $client_id = $this->client_id();

        $path_log = $dir_log;
        if (!empty($client_id)) {
            $dir_log .= $client_id . DIRECTORY_SEPARATOR;
            $path_log .= $client_id . DIRECTORY_SEPARATOR;
        }
        $path_log .= $this->filename_log();

        $ci = & get_instance();
        $controller = $ci->router->fetch_class();
        $action = $ci->router->fetch_method();
        

        //create new parts category if it has not existed yet
        if (!is_dir($dir_log)) {
            mkdir($dir_log, 0777, TRUE);
        }

        if (!file_exists($path_log)) {
            $message .= "";
        }

        if (!$fp = @fopen($path_log, FOPEN_WRITE_CREATE)) {
            return FALSE;
        }

        if (!isset($this->process_id) || empty($this->process_id)) {
            $process = $controller;
        } else {
            $process = $this->process_id;
        }

        $message .= date('Y/m/d H:m:s') . ' [ ' . strtoupper($process) . ' ] ' . strtoupper($action) . ' ACTION ' . $log . "\r\n";

        flock($fp, LOCK_EX);
        fwrite($fp, $message);
        flock($fp, LOCK_UN);
        fclose($fp);
        @chmod($path_log, FILE_WRITE_MODE);
        return TRUE;
    }

    /**
     * Write sql query to log
     */
    public function log_sql_query() {
        $ci = & get_instance();
        if (strpos($ci->db->last_query(), 'INSERT') !== FALSE || strpos($ci->db->last_query(), 'DELETE') !== FALSE || strpos($ci->db->last_query(), 'UPDATE') !== FALSE) {
            $this->log('SQL QUERY Info: ' . $ci->db->last_query());
        }
    }

    /*     * ********************************************************* */
    /*          MAGIC METHOD                                           */
    /*     * ********************************************************* */

    /**
     * Set variable
     * @param type $key | array | string
     * @param type $value | string
     * @return null
     */
    private function set($key, $value = '') {
        if (empty($key))
            return null;

        if (is_array($key)) {
            foreach ($key as $key => $value) {
                $this->__set($key, $value);
            }
        } else {
            $this->__set($key, $value);
        }
    }

    public function __set($key, $value) {
        $this->extend_var[$key] = $value;
    }

    public function __get($key) {
        if (array_key_exists($key, $this->extend_var)) {
            return $this->extend_var[$key];
        }
        $trace = debug_backtrace();
        trigger_error(
                'Undefined property via __get(): ' . $key .
                ' in ' . $trace[0]['file'] .
                ' on line ' . $trace[0]['line'], E_USER_NOTICE);
        return null;
    }

    public function __isset($name) {
        return isset($this->extend_var[$name]);
    }

    public function __unset($name) {
        unset($this->extend_var[$name]);
    }

}

?>
